package pe.com.cotelasa.scp.controlador;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.MathContext;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.inject.Inject;
import javax.inject.Named;
import org.springframework.context.annotation.Scope;

import org.apache.log4j.Logger;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import pe.com.cotelasa.common.controlador.MBGenerico;
import pe.com.cotelasa.scp.controlador.backingBean.BKDetalleOrdenCompraServicio;
import pe.com.cotelasa.scp.controlador.backingBean.BKOrdenCompra;
import pe.com.cotelasa.scp.dominio.common.ESTADO_REGISTRO;
import pe.com.cotelasa.scp.dominio.common.util.UtilitarioArchivos;
import pe.com.cotelasa.scp.dominio.service.IServicioTipoUnidadMinima;
import pe.com.cotelasa.scp.dominio.service.IServicioDetalleOrdenCompraServicio;
import pe.com.cotelasa.scp.dominio.service.IServicioProveedorArticulo;
import pe.com.cotelasa.scp.dominio.service.IServicioArticulo;
import pe.com.cotelasa.scp.dominio.service.IServicioTipoMoneda;
import pe.com.cotelasa.scp.dominio.excepcion.ServiceException;
import pe.com.cotelasa.scp.dominio.common.util.UtilitarioNumeroALetras;
import pe.com.cotelasa.scp.dominio.service.IServicioUnidadMedidaComp;
import pe.com.cotelasa.scp.entidad.Articulo;
import pe.com.cotelasa.scp.entidad.DetalleOrdenCompraServicio;
import pe.com.cotelasa.scp.entidad.ProveedorArticulo;
import pe.com.cotelasa.scp.entidad.TipoUnidadMinima;
import pe.com.cotelasa.scp.entidad.UnidadMedidaComp;
import pe.com.cotelasa.seguridad.controlador.backingBean.BKSession;

/**
 *
 * @author usuario
 */
@Named(value = "MBDetalleOrdenCompra")
@Scope("request")
public class MBDetalleOrdenCompra extends MBGenerico implements Serializable {

    private static Logger logger = Logger.getLogger(MBOrdenCompra.class);
    @Inject
    private BKDetalleOrdenCompraServicio bkDetalleOrdenCompra;
    @Inject
    private BKOrdenCompra bkOrdenCompra;
    @Inject
    private IServicioTipoUnidadMinima servicioTipoUnidadMinima;
    /*@Inject
     private IServicioProveedorArticulo servicioProveedorArticulo;*/
    @Inject
    private IServicioArticulo servicioArticulo;
    @Inject
    private IServicioUnidadMedidaComp servicioUnidadMedidaComp;
    @Autowired
    BKSession session;

    public MBDetalleOrdenCompra() {
    }

    private String generateAuthCode() {
        System.out.println("Entering generateAuthCode()");
        //getting the current time in nanoseconds
        long decimalNumber = System.nanoTime();
        System.out.println("current time in nanoseconds: " + decimalNumber);

        //To convert time stamp to alphanumeric code.
        //We need to convert base10(decimal) to base36
        String strBaseDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String strTempVal = "";
        int mod = 0;
        int authCodeLength = 0;
        // String concat is costly, instead we could have use stringbuffer or stringbuilder
        //but here it wont make much difference.
        while (decimalNumber != 0 && authCodeLength < 8) {
            mod = (int) (decimalNumber % 36);
            strTempVal = strBaseDigits.substring(mod, mod + 1) + strTempVal;
            decimalNumber = decimalNumber / 36;
            authCodeLength++;
        }
        System.out.println("alphanumeric code generated from TimeStamp : " + strTempVal);
        return strTempVal;

    }

    public void nuevoDetalle(ActionEvent actionEvent) {

        bkDetalleOrdenCompra.setDetalleOrdenCSFormulario(new DetalleOrdenCompraServicio());
        bkDetalleOrdenCompra.getDetalleOrdenCSFormulario().setPrecioForm(BigDecimal.ZERO);
        bkDetalleOrdenCompra.getDetalleOrdenCSFormulario().setCantidadForm(BigDecimal.ZERO);
        bkDetalleOrdenCompra.setImagenDetalle(null);
        bkDetalleOrdenCompra.setIdTipoUnidadMinimaFormulario(null);
        bkDetalleOrdenCompra.setIdArticuloFormulario(new Articulo());
        bkDetalleOrdenCompra.getDetalleOrdenCSFormulario().setTotalRecibido(BigDecimal.ZERO);
        bkDetalleOrdenCompra.setTipoAccion('a');
        try {
            if (bkDetalleOrdenCompra.getListaTipoUnidadMinima() == null) {
                bkDetalleOrdenCompra.setListaTipoUnidadMinima(servicioTipoUnidadMinima.listarTipoUnidadMinimasActivos());
            }


            //if (bkOrdenCompra.getListaDetalleOrdenCompraServicio() == null || bkDetalleOrdenCompra.getListaArticulo() == null) {

            /*ProveedorArticulo proveArt = new ProveedorArticulo();
             proveArt.setProveedor(bkOrdenCompra.getOrdenCompraFormulario().getIdProveedor());
             proveArt.setArticulo(new Articulo());
             proveArt.getArticulo().setIdCategoriaArticulo(bkOrdenCompra.getOrdenCompraFormulario().getIdCategoriaArticulo());

             Collection<ProveedorArticulo> listaProv = servicioProveedorArticulo.listarArticulosPorProveedor(proveArt);*/
            bkDetalleOrdenCompra.setListaArticulo(new ArrayList<Articulo>());
            //for (ProveedorArticulo prov : listaProv) {
            for (Articulo art : bkOrdenCompra.getListaArticuloCat()) {
                bkDetalleOrdenCompra.getListaArticulo().add(art);
            }

            //}


            if (bkDetalleOrdenCompra.getListaArticulo().isEmpty()) {
                bkDetalleOrdenCompra.setListaArticulo(null);
            }
            // }
            if (bkOrdenCompra.getListaDetalleOrdenCompraServicio() != null) {
                if (!bkOrdenCompra.getListaDetalleOrdenCompraServicio().isEmpty()) {
                    for (DetalleOrdenCompraServicio det : bkOrdenCompra.getListaDetalleOrdenCompraServicio()) {
                        Iterator itr = this.bkDetalleOrdenCompra.getListaArticulo().iterator();


                        while (itr.hasNext()) {
                            Articulo art = (Articulo) itr.next();
                            if (det.getIdArticulo().getId().equals(art.getId())) {
                                itr.remove();
                                break;
                            }
                        }
                    }
                }
            }

        } catch (ServiceException e) {
            mostrarError("Ocurrieron algunos problemas al cargar la informacion. Vuelva a intentar.");
            logger.error(e.getMessage(), e);
        }
    }

    public void editarDetalle() {
        bkDetalleOrdenCompra.setEliminarImagen(false);
        try {
            DetalleOrdenCompraServicio detalle = bkDetalleOrdenCompra.getDetalleOrdenCSFormulario();
            bkDetalleOrdenCompra.setDetalleOrdenCSSeleccionado(detalle);
            bkDetalleOrdenCompra.setIdArticuloFormulario(servicioArticulo.conseguirArticuloPorId(detalle.getIdArticulo().getId()));
            bkDetalleOrdenCompra.setIdTipoUnidadMinimaFormulario(detalle.getIdTipoUnidadMinima().getId());
            bkDetalleOrdenCompra.setImagenDetalle(null);
            cargarUnidadesMedida();
            bkDetalleOrdenCompra.setTipoAccion('e');
            if (bkDetalleOrdenCompra.getListaTipoUnidadMinima() == null) {
                bkDetalleOrdenCompra.setListaTipoUnidadMinima(servicioTipoUnidadMinima.listarTipoUnidadMinimasActivos());
            }

            //if (bkDetalleOrdenCompra.getListaArticulo() == null) {

            /*ProveedorArticulo proveArt = new ProveedorArticulo();
             proveArt.setProveedor(bkOrdenCompra.getOrdenCompraFormulario().getIdProveedor());
             proveArt.setArticulo(new Articulo());
             proveArt.getArticulo().setIdCategoriaArticulo(bkOrdenCompra.getOrdenCompraFormulario().getIdCategoriaArticulo());

             Collection<ProveedorArticulo> listaProv = servicioProveedorArticulo.listarArticulosPorProveedor(proveArt);*/
            bkDetalleOrdenCompra.setListaArticulo(new ArrayList<Articulo>());

            //for (ProveedorArticulo prov : listaProv) {
            for (Articulo art : bkOrdenCompra.getListaArticuloCat()) {
                //if (art.equals(prov.getArticulo())) {
                bkDetalleOrdenCompra.getListaArticulo().add(art);
                //break;
                //}
            }

            //}

            if (bkDetalleOrdenCompra.getListaArticulo().isEmpty()) {
                bkDetalleOrdenCompra.setListaArticulo(null);
            }

            //}
            for (DetalleOrdenCompraServicio det : bkOrdenCompra.getListaDetalleOrdenCompraServicio()) {


                Iterator itr = this.bkDetalleOrdenCompra.getListaArticulo().iterator();


                while (itr.hasNext()) {
                    Articulo art = (Articulo) itr.next();
                    if (det.getIdArticulo().getId().equals(art.getId())) {
                        itr.remove();
                        break;
                    }
                }

            }
            bkDetalleOrdenCompra.getListaArticulo().add(bkDetalleOrdenCompra.getIdArticuloFormulario());
            calcularCantidadEquiv();
        } catch (ServiceException e) {
            mostrarError("Ocurrieron algunos problemas al cargar la informacion. Vuelva a intentar.");
            logger.error(e.getMessage(), e);
        }

    }

    public void agregarListaDetalles(ActionEvent actionEvent) {
        DetalleOrdenCompraServicio detalle = bkDetalleOrdenCompra.getDetalleOrdenCSFormulario();
        BigDecimal subtotal = detalle.getCantidadForm().multiply(detalle.getPrecioForm());

        BigDecimal igv = bkDetalleOrdenCompra.getIgvFormulario().getMonto().divide(BigDecimal.valueOf(100));

        if (bkDetalleOrdenCompra.getEstadoIgvFormulario() == 'c') {
            detalle.setPrecioForm(detalle.getPrecioForm().divide(igv.add(BigDecimal.ONE), MathContext.DECIMAL32));
            detalle.setSubTotal(subtotal.divide(igv.add(BigDecimal.ONE), MathContext.DECIMAL32));
        } else {
            detalle.setSubTotal(subtotal);
        }
        detalle.setPrecio(detalle.getSubTotal().divide(detalle.getCantidad(), MathContext.DECIMAL32));

        if (bkOrdenCompra.getListaDetalleOrdenCompraServicio() == null) {
            bkOrdenCompra.setListaDetalleOrdenCompraServicio(new ArrayList<DetalleOrdenCompraServicio>());
            //bkOrdenCompra.setListaTemporalDetalleOrdenCompraServicio(new ArrayList<DetalleOrdenCompraServicio>());
        }


        try {

            detalle.setIdArticulo(servicioArticulo.conseguirArticuloPorId(bkDetalleOrdenCompra.getIdArticuloFormulario().getId()));
            detalle.setEstadoRegistro(ESTADO_REGISTRO.ACTIVO.getValor());
            detalle.setNombreArticulo(detalle.getIdArticulo().getNombreComercial());
            String ext = "";
            if (bkDetalleOrdenCompra.getTipoAccion() == 'a') {
                detalle.setUsrCreacion(session.getUsuario().getUsuario());
                detalle.setFecCreacion(new Date());
                if (bkDetalleOrdenCompra.getImagenDetalle() != null) {
                    String[] imagen = StringUtils.split(bkDetalleOrdenCompra.getImagenDetalle().getFileName(), ".");
                    String nombre = generateAuthCode();
                    ext = imagen[imagen.length - 1];
                    detalle.setImagen(nombre + "." + ext);
                } else {
                    detalle.setImagen(null);
                }


                bkOrdenCompra.getListaDetalleOrdenCompraServicio().add(detalle);
                bkOrdenCompra.getListaTemporalDetalleOrdenCompraServicio().add(detalle);

                if (bkDetalleOrdenCompra.getImagenDetalle() != null) {
                    guardarImagenServer(bkDetalleOrdenCompra.getImagenDetalle(), serviceProperties.getProperty("path.server.imagen.ordenCS")
                            + detalle.getImagen());
                }

            } else {
                detalle.setUsrModificacion(session.getUsuario().getUsuario());
                detalle.setFecModificacion(new Date());
                if (bkDetalleOrdenCompra.getImagenDetalle() != null) {
                    String[] imagen = StringUtils.split(bkDetalleOrdenCompra.getImagenDetalle().getFileName(), ".");
                    ext = imagen[imagen.length - 1];
                    if (detalle.getImagen() == null) {
                        String nombre = generateAuthCode();
                        detalle.setImagen(nombre + "." + ext);
                    }
                }
                Integer i = bkOrdenCompra.getListaDetalleOrdenCompraServicio().indexOf(bkDetalleOrdenCompra.getDetalleOrdenCSSeleccionado());

                Integer j = bkOrdenCompra.getListaTemporalDetalleOrdenCompraServicio().indexOf(bkDetalleOrdenCompra.getDetalleOrdenCSSeleccionado());


                if (bkDetalleOrdenCompra.getImagenDetalle() != null) {
                    guardarImagenServer(bkDetalleOrdenCompra.getImagenDetalle(), serviceProperties.getProperty("path.server.imagen.ordenCS")
                            + detalle.getImagen());
                } else {
                    if (bkDetalleOrdenCompra.isEliminarImagen()) {
                        eliminarImagenServer(serviceProperties.getProperty("path.server.imagen.ordenCS") + detalle.getImagen());
                        detalle.setImagen(null);
                    }
                }

                bkOrdenCompra.getListaDetalleOrdenCompraServicio().set(i, detalle);
                bkOrdenCompra.getListaTemporalDetalleOrdenCompraServicio().set(j, detalle);

            }
            CalcularTotales(bkOrdenCompra.getListaDetalleOrdenCompraServicio());
            armarDescripcionOC(bkOrdenCompra.getListaDetalleOrdenCompraServicio());


        } catch (Exception e) {
            mostrarError("Ocurrieron algunos problemas al cargar la informacion. Vuelva a intentar.");
            logger.error(e.getMessage(), e);
        }


    }

    public void eliminarDetalle(ActionEvent actionEvent) throws ServiceException {

        DetalleOrdenCompraServicio detalleOrdenCompra = bkDetalleOrdenCompra.getDetalleOrdenCSSeleccionado();

        System.out.println("entroooooooooooo " + detalleOrdenCompra.getId());

        if (detalleOrdenCompra.getId() != null) {
            bkOrdenCompra.getListaDetalleOrdenCompraServicio().remove(detalleOrdenCompra);
            Integer i = bkOrdenCompra.getListaTemporalDetalleOrdenCompraServicio().indexOf(detalleOrdenCompra);

            detalleOrdenCompra.setFecModificacion(new Date());
            detalleOrdenCompra.setUsrModificacion(session.getUsuario().getUsuario());
            detalleOrdenCompra.setEstadoRegistro(ESTADO_REGISTRO.INACTIVO.getValor());

            bkOrdenCompra.getListaTemporalDetalleOrdenCompraServicio().set(i, detalleOrdenCompra);

        } else {
            Iterator itr = this.bkOrdenCompra.getListaDetalleOrdenCompraServicio().iterator();
            while (itr.hasNext()) {
                DetalleOrdenCompraServicio det = (DetalleOrdenCompraServicio) itr.next();
                System.out.println("articulo 1 !!!" + detalleOrdenCompra.getIdArticulo());
                System.out.println("articulo 2 !!!" + det.getIdArticulo());
                if (detalleOrdenCompra.getIdArticulo().getId().equals(det.getIdArticulo().getId())) {
                    System.out.println("entroo !!!");
                    itr.remove();
                    break;
                }
            }
            Iterator itr1 = this.bkOrdenCompra.getListaTemporalDetalleOrdenCompraServicio().iterator();
            if (bkOrdenCompra.getComando().getNombre().equals("Actualizar")) {
                while (itr1.hasNext()) {
                    DetalleOrdenCompraServicio det = (DetalleOrdenCompraServicio) itr1.next();
                    if (detalleOrdenCompra.getIdArticulo().equals(det.getIdArticulo())
                            && det.getEstadoRegistro() == ESTADO_REGISTRO.ACTIVO.getValor()) {
                        itr1.remove();
                        break;
                    }
                }
            }
        }
        /*if(detalleOrdenCompra.getImagen() != null){
         eliminarImagenServer(serviceProperties.getProperty("path.server.imagen.ordenCS")
         +detalleOrdenCompra.getImagen());
        
         }*/

        CalcularTotales(bkOrdenCompra.getListaDetalleOrdenCompraServicio());
        armarDescripcionOC(bkOrdenCompra.getListaDetalleOrdenCompraServicio());

        if (bkOrdenCompra.getListaDetalleOrdenCompraServicio().isEmpty()) {
            bkOrdenCompra.setListaDetalleOrdenCompraServicio(null);
        }

    }

    public void CalcularTotales(List<DetalleOrdenCompraServicio> listaDetalle) {

        BigDecimal subtotal = BigDecimal.ZERO;
        BigDecimal cantidadTotal = BigDecimal.ZERO;
        String um = "";
        for (DetalleOrdenCompraServicio detalle : listaDetalle) {
            subtotal = subtotal.add(detalle.getSubTotal());
            cantidadTotal = cantidadTotal.add(detalle.getCantidad());
            if(um.equalsIgnoreCase("")){
                um = detalle.getIdTipoUnidadMinima().getAbrev();
            }
        }
        bkOrdenCompra.getOrdenCompraFormulario().setCantidadTotal(cantidadTotal);
        bkOrdenCompra.getOrdenCompraFormulario().setUnidad(um);
        bkOrdenCompra.getOrdenCompraFormulario().setSubtotal(subtotal);
        System.out.println("importacion :"+ bkOrdenCompra.getOrdenCompraFormulario().getEsImportacion());
        if(bkOrdenCompra.getOrdenCompraFormulario().getEsImportacion() == 0){
            bkOrdenCompra.getOrdenCompraFormulario().setIgv(
                bkDetalleOrdenCompra.getIgvFormulario().getMonto().divide(BigDecimal.valueOf(100)).multiply(subtotal));
        }else{
            bkOrdenCompra.getOrdenCompraFormulario().setIgv(BigDecimal.ZERO);
        }
        

        bkOrdenCompra.getOrdenCompraFormulario().setTotal(
                bkOrdenCompra.getOrdenCompraFormulario().getIgv().add(subtotal));

        UtilitarioNumeroALetras util = new UtilitarioNumeroALetras();
        DecimalFormat decf = new DecimalFormat("###.##");

        bkOrdenCompra.getOrdenCompraFormulario().setExpresionTotal(
                util.Convertir("" + decf.format(bkOrdenCompra.getOrdenCompraFormulario().getTotal()), true, bkOrdenCompra.getOrdenCompraFormulario().getIdTipoMoneda().getNombre()));

    }

    public void cargarUnidadesMedida() {
        UnidadMedidaComp unidad = new UnidadMedidaComp();
        try {
            bkDetalleOrdenCompra.getDetalleOrdenCSFormulario().setIdTipoUnidadMinima(servicioTipoUnidadMinima.conseguirTipoUnidadMinimaPorId(bkDetalleOrdenCompra.getIdTipoUnidadMinimaFormulario()));
            unidad.setIdTipoUnidadMinima(bkDetalleOrdenCompra.getDetalleOrdenCSFormulario().getIdTipoUnidadMinima());
            bkDetalleOrdenCompra.setListaUnidadMedidaComp(servicioUnidadMedidaComp.listarUnidadMedidaCompPorUM(unidad));
        } catch (ServiceException e) {
            e.printStackTrace();
        }


    }

    public void calcularCantidadEquiv() {

        try {
            this.bkDetalleOrdenCompra.setCantEqui(servicioUnidadMedidaComp.conseguirUnidadMedidaCompPorvalCadena(this.bkDetalleOrdenCompra.getDetalleOrdenCSFormulario().getUnidadMedidaForm()).getValNumerico());
            calcularCantidadInvetario();
        } catch (ServiceException e) {
            e.printStackTrace();
        }
    }

    public void calcularCantidadInvetario() {
        this.bkDetalleOrdenCompra.getDetalleOrdenCSFormulario().setCantidad(this.bkDetalleOrdenCompra.getCantEqui().multiply(this.bkDetalleOrdenCompra.getDetalleOrdenCSFormulario().getCantidadForm()));

    }

    public void armarDescripcionOC(List<DetalleOrdenCompraServicio> listaDetalle) {
        bkOrdenCompra.getOrdenCompraFormulario().setDescripcion("");

        for (DetalleOrdenCompraServicio detalle : listaDetalle) {
            bkOrdenCompra.getOrdenCompraFormulario().setDescripcion(
                    bkOrdenCompra.getOrdenCompraFormulario().getDescripcion() + detalle.getIdArticulo().getNombreComercial() + " ");
        }

    }

    public void handleFileUpload(FileUploadEvent event) {
        bkDetalleOrdenCompra.setImagenDetalle(event.getFile());
        FacesMessage msg = new FacesMessage("Se subió la foto satisfactoriamente", event.getFile().getFileName());
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    private boolean guardarImagenServer(UploadedFile fileLogo, String logo) throws ServiceException {
        try {
            File archivoLogo = new File(logo);
            if (archivoLogo != null) {
                if (archivoLogo.exists()) {
                    UtilitarioArchivos.delete(archivoLogo);
                }
            }
            UtilitarioArchivos.copyInputStream(fileLogo.getInputstream(), archivoLogo);
            return true;
        } catch (IOException e) {
            throw new ServiceException(e);
        }

    }

    private boolean eliminarImagenServer(String logo) throws ServiceException {
        try {
            File archivoLogo = new File(logo);
            if (archivoLogo != null) {
                if (archivoLogo.exists()) {
                    UtilitarioArchivos.delete(archivoLogo);
                }
            }
            return true;
        } catch (IOException e) {
            throw new ServiceException(e);
        }

    }
}
